﻿namespace FML

#light
     


#if INTERACTIVE
#I @"C:\Program Files\Reference Assemblies\Microsoft\F#\1.0\Runtime\v2.0"
#I @"C:\Windows\Microsoft.NET\Framework\v2.0.50727"
#I @"C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5"

#r "mscorlib.dll"
#r "System.dll"
#r "System.Core.dll"
#r "C:\Users\jcm\Documents\projects\Monads\libs\FsCheck.dll"
#r "C:\Users\jcm\Documents\projects\Monads\libs\NunitCore.dll"
#r "C:\Users\jcm\Documents\projects\FML\FML\obj\Debug\Monads.dll"
#endif

module StateT =

 printf "State trans test\n\n"

 module Option = 

  open StateT.Option

  open  Microsoft.FSharp.Control
  open  Microsoft.FSharp.Control.LazyExtensions
  open FsCheck

  let (>>=) m f = stateOptionT.Bind (m, f)
  let ret = stateOptionT.Return
 
  quickCheck (fun  f a s-> run ((ret a) >>= f) s = run (f a)s )
  quickCheck (fun m s -> run (m >>= ret) s = run m s)
  quickCheck (fun m f g s -> run ((m >>= f) >>= g) s = run (m >>= (fun x -> f x >>= g)) s)

 module List = 

  open StateT.List

  open  Microsoft.FSharp.Control
  open  Microsoft.FSharp.Control.LazyExtensions
  open FsCheck

  let (>>=) m f = stateListT.Bind (m, f)
  let ret = stateListT.Return
 
  quickCheck (fun  f a s-> run ((ret a) >>= f) s = run (f a)s )
  quickCheck (fun m s -> run (m >>= ret) s = run m s)
  quickCheck (fun m f g s -> run ((m >>= f) >>= g) s = run (m >>= (fun x -> f x >>= g)) s)

 module Error = 

  open StateT.Error

  open  Microsoft.FSharp.Control
  open  Microsoft.FSharp.Control.LazyExtensions
  open FsCheck

  let (>>=) m f = stateErrorT.Bind (m, f)
  let ret = stateErrorT.Return
 
  
  quickCheck (fun  f a s-> run ((ret a) >>= f) s = run (f a)s )
  quickCheck (fun m s -> run (m >>= ret) s = run m s)
  quickCheck (fun m f g s -> run ((m >>= f) >>= g) s = run (m >>= (fun x -> f x >>= g)) s)

 module Reader = 

  open StateT.Reader
  open ReaderM

  open  Microsoft.FSharp.Control
  open  Microsoft.FSharp.Control.LazyExtensions
  open FsCheck

  let (>>=) m f = stateReaderT.Bind (m, f)
  let ret = stateReaderT.Return

  let runS = StateT.Reader.run
  let runR = ReaderM.run
 
  
  quickCheck (fun  f a s env-> runR ( runS ((ret a) >>= f) s) env = runR (runS (f a) s ) env)
  quickCheck (fun m s env -> runR (runS (m >>= ret) s) env = runR (runS m s) env)
  quickCheck (fun m f g s env -> runR( runS ((m >>= f) >>= g) s) env = runR ( runS (m >>= (fun x -> f x >>= g)) s) env) 

 module Writer = 

  open StateT.Writer
  open WriterM
  open Monoid

  open  Microsoft.FSharp.Control
  open  Microsoft.FSharp.Control.LazyExtensions
  open FsCheck
  
  let monoid = new ListMonoid<int>() :> Monoid<int list>

  let writerM = WriterBuilder<int list>(monoid) :> IWriterMonad<int list>

  let stateWriterT = new StateWriterBuilder<int list>(writerM) :> IStateWriterTrans<int list>
  
  let (>>=) m f = stateWriterT.Bind (m, f)
  let ret = stateWriterT.Return

  let runW = StateT.Writer.run
 
  
  quickCheck (fun  f a s-> runW ((ret a) >>= f) s = runW (f a) s )
  quickCheck (fun m s -> runW (m >>= ret) s = runW m s)
  quickCheck (fun m f g s -> runW ((m >>= f) >>= g) s = runW (m >>= (fun x -> f x >>= g)) s)
